package com.crs.service.impl;

import com.crs.context.BaseContext;
import com.crs.dto.BaseReviewDTO;
import com.crs.dto.OwnerReplyDTO;
import com.crs.dto.UserFirstReviewDTO;
import com.crs.dto.UserReviewDTO;
import com.crs.entity.Borrow_record;
import com.crs.entity.Review;
import com.crs.exception.BusinessException;
import com.crs.mapper.BorrowMapper;
import com.crs.mapper.ReviewMapper;
import com.crs.mapper.UserMapper;
import com.crs.service.CreditService;
import com.crs.service.ReviewService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.crs.constant.EntityConstant;

import java.time.LocalDateTime;

import static com.crs.constant.EntityConstant.*;

@Service
public class ReviewServiceImpl implements ReviewService {

    @Autowired
    private ReviewMapper reviewMapper;

    @Autowired
    private BorrowMapper borrowMapper;

    @Autowired
    private CreditService creditService;

    @Autowired
    private UserMapper userMapper;

    @Transactional
    public void userFirstReview(UserFirstReviewDTO userFirstReviewDTO){
        //调用方法判断当前借阅记录是否已完成，完成才可以评价
        Borrow_record record = validateBorrowRecord(userFirstReviewDTO.getBorrowId());

        if(record == null){
            throw new BusinessException("当前记录不存在");
        }

        //判断评分是否小于等于2
        if(userFirstReviewDTO.getRating() <= 2){
            //收到差评扣除用户信用分
            //TODO 代码有问题扣减的是评论人的积分
            creditService.CreditEventInsert(BaseContext.getCurrentId(),RECEIVE_BAN, userFirstReviewDTO.getBorrowId());
        }

        //插入评价记录
        Review review = Review.builder()
                .reply(null)
                .replyTime(null)
                .status(1)
                .likeCount(0)
                .resourceId(record.getResourceId())
                .userId(BaseContext.getCurrentId())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        BeanUtils.copyProperties(userFirstReviewDTO,review);

        reviewMapper.submitReview(review);

        //看是否有加分资格然后加分
        IncreaseCommentScores(userFirstReviewDTO.getBorrowId());

    }

    @Transactional
    @Override
    public void  userReview(UserReviewDTO userReviewDTO) {
        //调用方法判断是否可以评论
        Borrow_record record = validateBorrowRecord(userReviewDTO.getBorrowId());
        //对记录进行校验
        validateParentReview(userReviewDTO.getParentReviewId());

        //插入评价记录
        Review review = Review.builder()
                .reply(null)
                .replyTime(null)
                .status(1)
                .likeCount(0)
                .resourceId(record.getResourceId())
                .userId(BaseContext.getCurrentId())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        BeanUtils.copyProperties(userReviewDTO,review);

        reviewMapper.submitReview(review);

        //看是否有加分资格然后加分
        IncreaseCommentScores(userReviewDTO.getBorrowId());
    }

    /**
     * 资源拥有者对记录进行回复
     * @param ownerReplyDTO
     */
    @Transactional
    @Override
    public void reply(OwnerReplyDTO ownerReplyDTO) {
        //首先根据reviewId查询到要回复的记录的各种属性
        Review review = reviewMapper.findById(ownerReplyDTO.getParentReviewId());
        //判断评论是否存在
        if(review==null){
            throw new BusinessException("该评论不存在");
        }
        //判断要回复的评论状态是否为正常  1
        if(review.getStatus()!=1){
            throw new BusinessException("该评论不能回复");
        }
        //资源拥有者只能回复一次,只能有一条记录指向上一条记录的id
        if(reviewMapper.existsByParentReviewId(review.getId())>0){
            throw new BusinessException("该评论已经回复过了，不能再进行评论");
        }
        Review review1 = Review.builder()
                .borrowId(review.getBorrowId())
                .resourceId(review.getResourceId())
                .userId(BaseContext.getCurrentId())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .rating(null)
                .status(1)
                .replyTime(LocalDateTime.now())
                .build();
        //属性拷贝会把parentReviewId设置为上一条评论的id
        BeanUtils.copyProperties(ownerReplyDTO,review1);

        //插入回复
        reviewMapper.insertReview(review1);

        //看是否有加分资格然后加分
        IncreaseCommentScores(review1.getBorrowId());
    }

    /**
     * 更新点赞数量
     * @param reviewId
     */
    @Transactional
    @Override
    public void updateLike(Long reviewId) {
       //更新点赞数量
        reviewMapper.updateLike(reviewId);
        //判断该用户今天是否加过分了,如果没加过
        if(userMapper.findById(BaseContext.getCurrentId()).getHasLikedToday() != 1){
            //增加分数
            creditService.CreditEventInsert(BaseContext.getCurrentId(),LIKE,null);
        }
    }

    public Borrow_record validateBorrowRecord(Long borrowId){
        //首先判断借用记录的状态是否是已完成
        Borrow_record record = borrowMapper.findById(borrowId);
        if(record == null){
            throw new BusinessException("没有该条借用记录");
        }
        if(record.getStatus()!=3){
            throw new BusinessException("商品未归还不能评价");
        }
        return record;
    }

    public void validateParentReview(Long parentReviewId){

        Review review = reviewMapper.findById(parentReviewId);

        if(review == null){
            throw new BusinessException("要回复的评论不存在");
        }
//        if(reviewMapper.findById(review.getId()) == null){
//            throw new BusinessException("要回复的评论不存在");
//        }
        //首先判断记录是否已经被回复了
        if(reviewMapper.existsByParentReviewId(parentReviewId)>0){
            throw new BusinessException("该评论已经回复过了，不能继续评论");
        }
        //判断该条评论是否可以回复
        if(review.getStatus() != 1){
            throw new BusinessException("该评论不能回复");
        }

        //TODO 由于apifox只能测试单个用户，不能测试自己回复自己这种情况
        //用户必须回复的是资源拥有者
//        if(){
//            throw new BusinessException("用户只能回复资源拥有者");
//        }
        //用户不能回复自己
//        if(review.getUserId() == BaseContext.getCurrentId()){
//            throw new BusinessException("用户不能回复自己的评论");
//        }
    }

    public void IncreaseCommentScores(Long borrowId){
        //判断今天评论是否加过分了
        if(userMapper.findById(BaseContext.getCurrentId()).getHasCommentedToday() !=1){
            //加分
            try {
                creditService.CreditEventInsert(BaseContext.getCurrentId(),COMMENT, borrowId);
                userMapper.updateHasCommentedToday(BaseContext.getCurrentId());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
